﻿#include "VAOneXMLAdaptorAcousticsNCTLayUp.h"

#include "FITKAcousticsPhysics/FITKAcousticsNCTLayUp.h"
#include "rapidxml.hpp"
#include "FITKAcousticsPhysics/FITKAcousticsNCTRegularTrimLayer.h"
#include "FITKAcousticsPhysics/FITKAcousticsNCTResistive.h"
#include "FITKAcousticsPhysics/FITKAcousticsNCTSeptum.h"
#include "FITKAcousticsPhysics/FITKAcousticsNCTPerforated.h"
#include "VAOneXMLAdaptorAcousticsNCTRegularTrimLayer.h"
#include "VAOneXMLAdaptorAcousticsNCTSeptum.h"
#include "VAOneXMLAdaptorAcousticsNCTPerforated.h"
#include "VAOneXMLAdaptorAcousticsNCTResistiveTrimLayer.h"

#include <QDebug>

namespace IO
{

    bool VAOneXMLAdaptorAcousticsNCTLayUp::adaptR()
    {

        return readNCTLayUp();
    }

    bool VAOneXMLAdaptorAcousticsNCTLayUp::adaptW()
    {
        return writeNCTLayUp();
    }

    bool VAOneXMLAdaptorAcousticsNCTLayUp::readNCTLayUp()
    {
        // 指针判断是否为空
        if(!_node)
        {
            return false;
        }

        if(!_dataObj)
        {
            return false;
        }

        //转换成多层声学包类
        Acoustics::FITKAcousticsNCTLayUp* data = dynamic_cast<Acoustics::FITKAcousticsNCTLayUp*>(_dataObj);

        if(!data)
        {
            return false;
        }

        //数据读取状态 默认为true
        bool b = true;
        // 读取各项属性
        // 每个属性可能存在缺省配置
        double dValue = readDoubleAttribute(_node, "maxfieldangle", &b);// 读取最大仰角度

        if(b)
        {
            data->setMaxFieldAngle(dValue);
        }

        auto nameNode = _node->first_node("Name")->first_node();

        if (nameNode == nullptr)
        {
            //数据中 名称为必要项 不可为空 并抛出异常日志
            consoleMessage(2, "NCTLayUp name is null");
            return false;
        }

        QString strName = readStrNodeValue(nameNode, &b);

        if(b)
        {
            data->setDataObjectName(strName);//名称可以为空，但是节点不能为空
        }

        auto noteNode = _node->first_node("Note");
        if (noteNode != nullptr)
        {
            QString strNote = readStrNodeValue(noteNode, &b);
            ///预留
        }

        //获取颜色节点
        auto colorNode = _node->first_node("Color");
        float colorR = 0; float colorG = 0; float colorB = 0;
        //根据节点获取颜色
        readColorNodeValue(colorNode, colorR, colorG, colorB);
        //设置颜色
        data->setColor(colorR, colorG, colorB);

        readreadNCTAbstractLay();

        return true;
    }

    bool VAOneXMLAdaptorAcousticsNCTLayUp::writeNCTLayUp()
    {
        if (!_node)// 判断节点是否存在
        {
            return false;
        }

        //转换类型
        Acoustics::FITKAcousticsNCTLayUp* data = dynamic_cast<Acoustics::FITKAcousticsNCTLayUp*>(_dataObj);

        if(!data)
        {
            return false;
        }

        // 创建名称节点
        createNodeElement(_node, "Name", data->getDataObjectName());
        // 创建备注节点
        createNodeElement(_node, "Note", "");
        //创建颜色节点
        auto colorNode = createNodeElement(_node, "Color");

        //写入颜色节点信息
        if(colorNode)
        {
            float rgb[3] = {0.1f, 0.3f, 0.4f};
            data->getColor(rgb);
            writeAttribute(colorNode, "colorR", rgb[0]);
            writeAttribute(colorNode, "colorG", rgb[1]);
            writeAttribute(colorNode, "colorB", rgb[2]);
        }

        writeAttribute(_node, "maxfieldangle", data->getMaxFieldAngle());

        //写层信息
        writereadNCTAbstractLay();
        return true;
    }

    bool VAOneXMLAdaptorAcousticsNCTLayUp::readreadNCTAbstractLay()
    {

        auto trimLayerNode = _node->first_node("TrimLayer");

        if(!trimLayerNode)//如果为空，则返回
        {
            return true;
        }

        int index = 0;

        while (trimLayerNode)
        {
            auto regularTrimLayerNode = trimLayerNode->first_node("RegularTrimLayer");//常规板

            if(regularTrimLayerNode)
            {
                readTrimLayer(index, 0, regularTrimLayerNode);
            }

            auto septumTrimLayerNode = trimLayerNode->first_node("SeptumTrimLayer");//隔离层

            if(septumTrimLayerNode)
            {
                readTrimLayer(index, 1, septumTrimLayerNode);
            }

            auto perforatedTrimLayer = trimLayerNode->first_node("PerforatedTrimLayer");//多孔介质

            if(perforatedTrimLayer)
            {
                readTrimLayer(index, 2, perforatedTrimLayer);
            }

            auto resistiveTrimLayer = trimLayerNode->first_node("ResistiveTrimLayer");//阻尼

            if(resistiveTrimLayer)
            {
                readTrimLayer(index, 3, resistiveTrimLayer);
            }

            trimLayerNode = trimLayerNode->next_sibling("TrimLayer");
            index++;
        }

        return true;
    }

    bool VAOneXMLAdaptorAcousticsNCTLayUp::writereadNCTAbstractLay()
    {
        //转换类型
        Acoustics::FITKAcousticsNCTLayUp* data = dynamic_cast<Acoustics::FITKAcousticsNCTLayUp*>(_dataObj);
        IO::FITKAbstractVAOneXMLAdaptor* adaptor {};//操作器
        int dataCount = data->getDataCount();
        bool b = true;

        for(int i = 0; i < dataCount; i++)
        {
           //创建写操作器
           //根据类型获取应该创建什么操作器
           auto layerData = data->getDataByIndex(i);

           if(!layerData)
           {
               continue;
           }

            Acoustics::FITKAcousticsNCTAbstractLayObj::NCTLayUpType type = layerData->getNCTLayUpType();

            switch (type)
            {
                case Acoustics::FITKAcousticsNCTAbstractLayObj::NCTLayUpType::Foam:
                case Acoustics::FITKAcousticsNCTAbstractLayObj::NCTLayUpType::Gap:
                case Acoustics::FITKAcousticsNCTAbstractLayObj::NCTLayUpType::Panel:
                case Acoustics::FITKAcousticsNCTAbstractLayObj::NCTLayUpType::Fiber:
                    // 对于泡沫、缝隙、实体和纤维类型，转换为RegularTrimLayer并创建相应适配器
                    layerData = dynamic_cast<Acoustics::FITKAcousticsNCTRegularTrimLayer*>(layerData);
                    adaptor = FITKIOADAPTORFACTORY->createT<IO::VAOneXMLAdaptorAcousticsNCTRegularTrimLayer>("VAOneXML", layerData);
                    break;

                case Acoustics::FITKAcousticsNCTAbstractLayObj::NCTLayUpType::Perforated:
                    // 对于多孔类型，转换为Perforated并创建相应适配器
                    layerData = dynamic_cast<Acoustics::FITKAcousticsNCTPerforated*>(layerData);
                    adaptor = FITKIOADAPTORFACTORY->createT<IO::VAOneXMLAdaptorAcousticsNCTPerforated>("VAOneXML", layerData);
                    break;

                case Acoustics::FITKAcousticsNCTAbstractLayObj::NCTLayUpType::Resistive:
                    // 对于阻尼类型，转换为Resistive并创建相应适配器
                    layerData = dynamic_cast<Acoustics::FITKAcousticsNCTResistive*>(layerData);
                    adaptor = FITKIOADAPTORFACTORY->createT<IO::VAOneXMLAdaptorAcousticsNCTResistiveTrimLayer>("VAOneXML", layerData);
                    break;

                case Acoustics::FITKAcousticsNCTAbstractLayObj::NCTLayUpType::Septum:
                    // 对于隔离类型，转换为Septum并创建相应适配器
                    layerData = dynamic_cast<Acoustics::FITKAcousticsNCTSeptum*>(layerData);
                    adaptor = FITKIOADAPTORFACTORY->createT<IO::VAOneXMLAdaptorAcousticsNCTSeptum>("VAOneXML", layerData);
                    break;

                default:
                    // 如果类型不匹配上述任何一种，可以在这里处理默认情况或者抛出异常
                    // 例如：throw std::runtime_error("Unsupported layer type.");
                    break;
            }

            //创建层节点
            rapidxml::xml_node<char>* layerNode = createNodeElement(_node, "TrimLayer");
            adaptor->setNode(layerNode);
            adaptor->setDataObject(layerData);
            b &= adaptor->adaptW();
            delete adaptor;//删除操作器
            adaptor = nullptr;

        }
        return b;
    }

    bool VAOneXMLAdaptorAcousticsNCTLayUp::readTrimLayer(int index, int type,rapidxml::xml_node<char>* node)
    {
        bool b = true;
        IO::FITKAbstractVAOneXMLAdaptor* adaptor {};
        Acoustics::FITKAcousticsNCTAbstractLayObj* data {};

        switch (type)
        {
            case 0:
                // 类型0对应RegularTrimLayer
                data = new Acoustics::FITKAcousticsNCTRegularTrimLayer;
                adaptor = FITKIOADAPTORFACTORY->createT<IO::VAOneXMLAdaptorAcousticsNCTRegularTrimLayer>("VAOneXML", data);
                break;

            case 1:
                // 类型1对应Septum
                data = new Acoustics::FITKAcousticsNCTSeptum;
                adaptor = FITKIOADAPTORFACTORY->createT<IO::VAOneXMLAdaptorAcousticsNCTSeptum>("VAOneXML", data);
                break;

            case 2:
                // 类型2对应Perforated
                data = new Acoustics::FITKAcousticsNCTPerforated;
                adaptor = FITKIOADAPTORFACTORY->createT<IO::VAOneXMLAdaptorAcousticsNCTPerforated>("VAOneXML", data);
                break;

            case 3:
                // 类型3对应Resistive
                data = new Acoustics::FITKAcousticsNCTResistive;
                adaptor = FITKIOADAPTORFACTORY->createT<IO::VAOneXMLAdaptorAcousticsNCTResistiveTrimLayer>("VAOneXML", data);
                break;

            default:
                // 如果类型不匹配上述任何一种，则返回true，这里假设返回true表示成功处理
                return true;
        }


        if(!adaptor)
        {
            //读写器创建异常
            consoleMessage(3,"create adaptor Error");
            return false;
        }

        adaptor->setNode(node);
        adaptor->setDataObject(data);
        b &= adaptor->adaptR();
        delete adaptor;//删除操作器
        adaptor = nullptr;
        //转换成多层声学包类
        Acoustics::FITKAcousticsNCTLayUp* dataLayUp = dynamic_cast<Acoustics::FITKAcousticsNCTLayUp*>(_dataObj);

        //在这里判断是否存在读取的层信息
        auto layerDataOld = dataLayUp->getDataByIndex(index);

        if(!layerDataOld)//如果为空，则插入到数据类中
        {
            dataLayUp->insertDataObj(index, data);
        }
        else//不为空，则复制当前数据类
        {
            layerDataOld->copy(data);
            delete data;//删除创建的数据
        }

        //读取成功
        return b;
    }
}
